package com.yty.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yty.product.apidata.OrderDetailInput;
import com.yty.product.apidata.ProductInfoOutput;
import com.yty.product.entity.ProductInfo;
import com.yty.product.enums.DataDictionary;
import com.yty.product.exception.ProductRuntimeException;
import com.yty.product.mapper.ProductInfoMapper;
import com.yty.product.message.StockChangedMessage;
import com.yty.product.service.ProductInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ProductInfoServiceImpl extends ServiceImpl<ProductInfoMapper, ProductInfo> implements ProductInfoService {
    @Resource
    private AmqpTemplate fanoutAmqpTemplate;

    @Override
    public List<ProductInfo> listOnShelves() {
        return this.listByStatus(DataDictionary.PRODUCT_STATUS_ON_SHELVES.getValue());
    }

    @Override
    public List<ProductInfoOutput> listInProductId(List<String> productIds) {
        return super.list(new LambdaQueryWrapper<ProductInfo>().in(ProductInfo::getProductId, productIds))
                .stream().map(ProductInfo::toProductInfoOutput).collect(Collectors.toList());
    }

    @Override
    @Transactional
    public void decreaseStock(List<OrderDetailInput> orderDetailInputs) {
        List<StockChangedMessage> stockChangedMessageList = orderDetailInputs.stream().map(input -> {
            String productId = input.getProductId();
            //减库存
            Integer newStock = this.decreaseStock(productId, input.getProductQuantity());
            //收集最新库存
            StockChangedMessage stockChangedMessage = new StockChangedMessage();
            stockChangedMessage.setProductId(productId);
            stockChangedMessage.setStock(newStock);
            return stockChangedMessage;
        }).collect(Collectors.toList());
        //广播减库存消息
        stockChangedMessageList.forEach(fanoutAmqpTemplate::convertAndSend);
    }

    /**
     * 减库存
     *
     * @param productId
     * @param quantity
     * @return 最新库存
     */
    private Integer decreaseStock(String productId, Integer quantity) {
        ProductInfo productInfo = super.getOne(new LambdaQueryWrapper<ProductInfo>()
                .eq(ProductInfo::getProductId, productId));
        Integer stock = productInfo.getProductStock();

        Integer newStock = stock - quantity;
        if (newStock < 0)
            //TODO 库存不足
            throw new ProductRuntimeException("库存不足，productId:{},stock:{},quantity:{}", productId, stock, quantity);

        ProductInfo update = new ProductInfo();
        update.setProductStock(newStock);
        super.update(update, new LambdaQueryWrapper<ProductInfo>()
                .eq(ProductInfo::getProductId, productInfo.getProductId()));

        return newStock;
    }

    /**
     * 按商品状态查询
     *
     * @param status
     * @return
     */
    private List<ProductInfo> listByStatus(Integer status) {
        return super.list(new LambdaQueryWrapper<ProductInfo>().eq(ProductInfo::getProductStatus, status));
    }
}
